#include <logger.hpp>
#include "CmdHandler.h"

xbase::client_environment_ptr CQueryCmdHandler::clientEnvironmentPtr_;

//void CQueryCmdHandler::process(const __CmdTriple & cmdTriple,XBaseClient & client,U32 & lastLoad)
void CQueryCmdHandler::process(const __CmdTriple & cmdTriple)
{
	//MAKE SURE THERE IS NOLY ONE WAY OUT
    LOG(DEBUG,"CQueryCmdHandler::process");
    QCmdBase * pCmd = cmdTriple.first;
    int fd = cmdTriple.second;
    __SockPtr pSock = fdSockMap_.GetSock(fd);
	
    if(!pSock || pSock != cmdTriple.third){
        LOG(WARN, "before process command(addr="<<pCmd<<",fd="<<fd
            <<"), old socket("<<cmdTriple.third->ToString()<<") is replaced by new socket("
            <<(pSock ? pSock->ToString() : "0x0")<<"), abandon it");
    }else{
    
        LOG(TRACE, "process command("<<QCmdBase::CommandName(pCmd->CmdType())<<") from "
            <<pSock->ToString());
		
        switch(pCmd->CmdType()){    //ADD NEW COMMAND HERE
            case CMD_QUERY:{
                processCmd(dynamic_cast<CQueryCmd &>(*pCmd), fd, pSock);
                break;}
            case CMD_INSERT:{
                processCmd(dynamic_cast<CInsertCmd &>(*pCmd));
                break;}
            default:
				LOG(ERROR, "unknown command type="<<pCmd->CmdType()<<" from "<<pSock->ToString()
                    <<" cmd="<<pCmd->ToString());
        }
    }
	
    QCmdBase::ReleaseCommand(pCmd);
}

void CQueryCmdHandler::processCmd(CQueryCmd & cmd, int fd, __SockPtr pSock)
{
	LOG(DEBUG, "CQueryCmdHandler::processCmd(CQueryComd &)");
	LOG(TRACE, "query command="<<cmd.ToString());

	CCommandStats stats(cmd.CmdType(), true);
	CQueryData * query = CQueryData::GetObject();
	CRespCmd resp(cmd);

	query->cid_.swap(cmd.cid_);
	query->offset_ = cmd.offset_;
	query->amount_ = cmd.amount_;
	query->fd_ = fd;
	query->oldSock_ = pSock;

	LOG(TRACE, "push CQueryData="<<query->ToString()<<" into queryQue_");
	if(!queryQue_.Push(__QueryQueItem(query, resp)))
	{
		LOG(ERROR, "push CQueryData="<<query->ToString()<<" into queryQue_ failed, destroy it");
		CQueryData::PutObject(query);
		stats.Succ(false);
	}
}

void CQueryCmdHandler::processCmd(CInsertCmd & cmd)
{
    LOG(DEBUG, "CQueryCmdHandler::processCmd(CInsertCmd &)");
    LOG(TRACE, "query command="<<cmd.ToString());
	
    CCommandStats stats(cmd.CmdType(),true);
    CInsertData * insert = CInsertData::GetObject();
	
    insert->cid_.swap(cmd.cid_);
    insert->gcid_.swap(cmd.gcid_);
    insert->peerId_.swap(cmd.peerId_);
    insert->fileSz_ = cmd.fileSz_;

	
    LOG(TRACE, "push CInsertData="<<insert->ToString()<<" into insertQue_");
    if(!insertQue_.Push(insert))
	{
        LOG(ERROR, "push CInsertData="<<insert->ToString()<<" into insertQue_ failed, destroy it");
        CInsertData::PutObject(insert);
        stats.Succ(false);
    }
}
